package com.bdcom.autotest.interaction.http;

import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.CountDownLatch;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.bdcom.autotest.interaction.bean.Netcard;
import com.bdcom.autotest.telnet.util.ping.Ping;

public class NetcardUtil {
	
	private static Logger log = LoggerFactory.getLogger(NetcardUtil.class);

	
	private static List<Netcard> allNetCards = null;
	private static Netcard selectedNetcard = null;
	
	private static HashMap<String, String> ipmask = new HashMap<>(); 
	private static Integer sync1 = new Integer(1);
	
	public static String[] getIPMASK() {
		synchronized (sync1) {
			if( ipmask.size()==0 ) {
				return null;
			}
			String next = ipmask.keySet().iterator().next();
			String remove = ipmask.remove(next);
			return new String[] {next , remove};
		}
	}
	
	public static void putIPMASK(String ip , String mask) {
		synchronized (sync1) {
			ipmask.put(ip, mask);
		}
	}
	
	public static void main(String[] args) throws Exception {
		loadAllNetcards();
		log.debug(   allNetCards.size()  +"" );
		log.debug(   selectedNetcard.toString()  );
		
	}
	
	
	public static List<Netcard> loadAllNetcards(){
		List<Netcard> res  = new ArrayList<>();
		
		try {
			Enumeration<NetworkInterface> allNetDevices = NetworkInterface.getNetworkInterfaces();
			while (allNetDevices.hasMoreElements()) {
				NetworkInterface networkInterface = allNetDevices.nextElement();
				String displayName = networkInterface.getDisplayName();
				// 获得正在 运行的 网卡信息
				if( networkInterface.isUp()  && !networkInterface.isLoopback()) {
					
					List<InterfaceAddress> interfaceAddresses = networkInterface.getInterfaceAddresses();
					for( InterfaceAddress interfaceAddr : interfaceAddresses ) {
						String ip = interfaceAddr.getAddress().getHostAddress() ;
						short mask = interfaceAddr.getNetworkPrefixLength()  ;
						if( ip == null || ip.contains(":")  ) {
							continue;
						}
						
						Netcard netcard = new Netcard( displayName , ip , mask);
						res.add( netcard);
						if ( selectedNetcard==null && !"127.0.0.1".equals(ip) ) {
							setSelectedNetcard( netcard);
						}
//						System.out.println(    displayName+ ":    " +  ip + " / " +  mask  );
					}
					
				}
			}
		} catch ( Exception e) {
			log.error( "" ,e  );
		}
		
		allNetCards = res;
		return res;
	}

	
	public static void setSelectedNetcard( Netcard sel  ) {
		selectedNetcard = sel;
		calcIPList();
	}

	public static Netcard getSelectedNetcard() {
		return selectedNetcard;
	}
	
	public static List<Netcard> getAllNetcards(){
		return allNetCards;
	}
	
	private static void calcIPList() {
		long t1 = System.currentTimeMillis();
		ipmask.clear();
		selectedNetcard.init();
		int ipCnt = 10;
		
//		String ip = selectedNetcard.getIp();
//		short mask = selectedNetcard.getMask();
//		String seg = ip + "/" + mask;
//		
//		String netMask = IpCaculate.getNetMask(mask+"");
//		String sip = IpCaculate.getStartIp(seg);
//		String eip = IpCaculate.getEndIp(seg);
//		log.info(  "网段掩码 与  起止IP: "+netMask  + " ,  "  + sip);
//		Long ipLong = IpCaculate.getIpFromString(sip);
		
//		int  trytimes = 100;
//		int counter = 0 ;
//		while ( ipmask.size() < ipCnt && (counter<trytimes)) {
//			
//			try {
//				counter++;
//				ipLong++;
//				String ipFromLong = IpCaculate.getIpFromLong(ipLong);
//				// ping test
//				boolean pingres = Ping.ping2(ipFromLong);
//				
//				if( !pingres ) {
//					ipmask.put(ipFromLong, netMask);
//					log.info( "待用 IP ：" +  ipFromLong    );
//				}
//			} catch (Exception e) {
//				log.error("" ,e );
//			}
//		}
		
		CountDownLatch latch = new CountDownLatch(ipCnt);
		for(   int i=0 ; i< ipCnt  ; i ++  ) {
			CalcIPThread ttt = new CalcIPThread(latch, selectedNetcard);
			ttt.start();
		}
		
		try {
			latch.await();
		} catch (InterruptedException e) {
			log.error( "" ,e );
		}
		
		long t2 = System.currentTimeMillis();
		
		log.info(   "  Calc ip  coast time : " + (( t2-t1 )  / 1000)+  "  s  ;  map size is : " + ipmask.size());
	}
	
}
class CalcIPThread extends Thread{
	
	private static Logger log = LoggerFactory.getLogger(CalcIPThread.class);
	
	
	CountDownLatch latch ;
	Netcard card;
	public CalcIPThread( CountDownLatch latch  ,   Netcard card){
		this.latch = latch;
		this.card = card;
	}
	
	@Override
	public void run() {
		int  trytimes = 4;
		int counter = 0 ;
		try {
			while ( (counter<trytimes)) {
				try {
					long ipLong = card.getOneLongIP();
					String netMask = card.getMastStr();
					String ipFromLong = IpCaculate.getIpFromLong(ipLong);
					log.debug(  "IP 连通性正在 测试" + ipFromLong );
					boolean pingres = Ping.ping2(ipFromLong);
					log.debug(  "IP 连通性 " + ipFromLong  + ( (pingres==true)?" 可达":" 不可达" )   );
					if( !pingres ) {
						NetcardUtil.putIPMASK(ipFromLong, netMask);
						log.info(  " 待用 IP ：" +  ipFromLong    );
						return;
					}
					
				} catch (Exception e) {
					log.error( "" ,e );
				}
			}
		} catch (Exception e) {
			log.error( "" , e);
		}finally {
			latch.countDown();
		}
		
		log.error( Thread.currentThread().getName() + "未找到可用IP" );
	}
	
}



